package com.iot08.common.service.base;

import com.mongodb.client.result.DeleteResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import javax.annotation.Resource;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;

/**
 * @version 1.0
 * @Description: service基类(admin), 部分基本查询的封装
 * @time: 2020/11/11 17:08
 * @author: Rock
 */
@Slf4j
public class BaseAdminService<T> {

    @Resource(name = "adminMongoTemplate")
    protected MongoTemplate mongoTemplate;

    /**
     * 获取泛型类的class
     *
     * @time: 2020/11/11 17:35
     * @author: Rock
     * @version 1.0
     */
    protected Class<T> getTClass() {
        return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 根据_id获取数据（单条记录）
     *
     * @param id
     * @time: 2020/11/11 17:39
     * @author: Rock
     * @version 1.0
     */
    public T findById(Object id) {
        return mongoTemplate.findById(id, getTClass());
    }

    /**
     * 保存
     *
     * @param entity
     * @time: 2020/11/11 17:50
     * @author: Rock
     * @version 1.0
     */
    public T save(T entity) {
        return mongoTemplate.save(entity);
    }

    /**
     * 根据_id更新数据
     *
     * @param id
     * @param update
     * @time: 2020/11/11 17:36
     * @author: Rock
     * @version 1.0
     */
    public void updateById(Object id, Update update) {
        if (update.getUpdateObject().isEmpty()) {
            log.warn("Update is Empty. id={}. getTClass={}", id, getTClass());
        } else {
            mongoTemplate.updateFirst(new Query(Criteria.where("_id").is(id)), update, getTClass());
        }
    }

    /**
     * @param query
     * @param update
     * @time: 2021/3/24 14:42
     * @author: Rock
     * @version 1.0
     */
    public void update(Query query, Update update) {
        if (update.getUpdateObject().isEmpty()) {
            log.warn("Update is Empty. query={}. getTClass={}", query, getTClass());
        } else {
            mongoTemplate.updateFirst(query, update, getTClass());
        }
    }

    /**
     * 根据_id删除（单条）
     *
     * @param id
     * @time: 2020/11/11 17:59
     * @author: Rock
     * @version 1.0
     */
    public boolean delById(Object id) {
        DeleteResult result = mongoTemplate.remove(new Query(Criteria.where("_id").is(id)), getTClass());
        if (result != null) {
            return result.getDeletedCount() > 0;
        }
        return false;
    }

    /**
     * 根据_id删除记录（多条，传入的参数为id列表）
     *
     * @param ids
     * @time: 2020/11/20 14:31
     * @author: Rock
     * @version 1.0
     */
    public long delByIds(Collection<?> ids) {
        DeleteResult result = mongoTemplate.remove(new Query(Criteria.where("_id").in(ids)), getTClass());
        if (result != null) {
            return result.getDeletedCount();
        }
        return 0l;
    }

    /**
     * 根据_id获取记录列表（传入参数为id列表）
     *
     * @param ids
     * @time: 2020/11/13 14:54
     * @author: Rock
     * @version 1.0
     */
    public List<T> listByIds(Collection<?> ids) {
        return mongoTemplate.find(new Query(Criteria.where("_id").in(ids)), getTClass());
    }

    /**
     * 根据条件查找单个记录
     *
     * @param query
     * @time: 2020/12/1 15:15
     * @author: Rock
     * @version 1.0
     */
    public T findOne(Query query) {
        return mongoTemplate.findOne(query, getTClass());
    }

    /**
     * 根据条件查找多个记录
     *
     * @param query
     * @time: 2020/12/1 15:16
     * @author: Rock
     * @version 1.0
     */
    public List<T> find(Query query) {
        return mongoTemplate.find(query, getTClass());
    }

    /**
     * 根据条件查询记录总数量
     *
     * @param query
     * @time: 2020/12/7 11:33
     * @author: Rock
     * @version 1.0
     */
    public long count(Query query) {
        return mongoTemplate.count(query, getTClass());
    }

}
